home *** CD-ROM | disk | FTP | other *** search
- Path: atglab.bls.com!Alun.Champion
- From: Alun.Champion@bridge.bst.bls.com (Alun Champion)
- Newsgroups: comp.lang.c
- Subject: Re: allocating unlimited string input....HELP
- Date: 10 Jan 1996 16:27:33 GMT
- Organization: Computer People Inc.
- Message-ID: <ALUN.CHAMPION.96Jan10112733@g7240065.bridge.bst.bls.com>
- References: <4d0e2c$4uq@clientlink.com>
- NNTP-Posting-Host: bstfirewall.bst.bls.com
- In-reply-to: Matthew Raffel's message of 10 Jan 1996 13:13:48 GMT
-
- In article <4d0e2c$4uq@clientlink.com> Matthew Raffel <raffelm@netcom.com> writes:
-
- : ryangall@gpu.srv.ualberta.ca (Bobby Sixkiller) writes:
-
- : A few things I may consider note worthy:
-
- : You need test B for a vailidity as a pointer.
- : EG:
- : if (!B)
- : printf("\nMalloc Failed");
-
- : Additionally, you are never freeing B before "realloc"ing
- : it. What is happening here, B gets set to point to
- : some hunk of memory, then gets pointed to another hunk
- : and another and so on. The pieces of memory B pointed to
- : a one point is never released back to the system. This could
- : be the cause of the failure after a fixed point, especially
- : if you are compiling in a small or compact memory model.
-
- In his original code - he never used realloc, you mean re-malloc. He assigned
- B to A and free'd A in the loop. The memory was not the cause for failure.
-
- : You can avoid "needing" A by using realloc which
- : will preserve the contents of the memory.
-
- : Below is a "rewrite" of your code to implement my thoughts.
- : One, note, I did not compile it so...look out :=)
-
- : int read(char *S)
-
- Probably not a good choice of name, though not defined in the standards many
- operating systems define their own read() and write() functions.
-
- : {
- : char *B = NULL;
- : char ch,count=0;
-
- This is more likely to be the cause of the failure, count is a char, which may
- be a signed char (implementation defined) and if this is the case has max value
- of 127 and would then wrap and become negative - this could cause a few
- problems. If it is not signed then its maximum value is 255 which is not
- really big enough to deal with strings of unlimited length ;')
-
- : int iCount = 0;
-
- : /* create an initial size */
- : B = malloc(6);
-
- The test for the malloc is buried deep in the loop
-
- : ch=getc(stdin);
-
- getc(stdin) is equivalent to getchar() and returns an int not a char.
-
- : while(ch!='\n')
-
- Should test EOF condition, for this reason getc() returns an int and not char.
-
- : {
- : /* only realloc every so often...increment memory size by 5 bytes each time
- : if (iCount == 5)
-
- Hard coding values is probably not a good idea.
-
- : {
- : B=(char *) realloc(B, count + 5);
-
- Cast is unnecessary in ansi C and should be removed. If the realloc fails
- you lose the space pointed to by B - a memory leak perhaps.
-
- : iCount = 0;
- : }
- : else
- : iCount ++;
-
- : if (!B)
- : {
- : printf("\nB does not exist");
-
- The '\n' should be at the end of the string or else you should explicitly flush
- the output.
-
- : break;
- : }
- : else
- : {
- : sprintf(B,"%s%c",B,ch);
-
- This is quite innefficient now as realloc retains the contents of B for you
- B[count] = ch;
- B[count+1] = '\0';
- and the '\0' terminating character is not accounted for in the realloc but
- it is in the malloc. You would have to add one to the realloc(). And it
- was not dealt with in the original program.
-
- : printf("%s---%i----%i\n",B,strlen(B),count);
- : }
- : ch=getc(stdin);
-
- if this was placed in the while expression you wouldn't need to repeat this
- statement.
-
- : count=count+1;
-
- Whats wrong with the increment operator ?;')
- count++;
-
- : }
-
- : /* copy results to return value */
- : if (S && B)
- : strcpy(S, B);
-
- This is probably not what the original poster wanted because this assumes he
- new the maximum size of the string when coming into the function, which
- is not the case as this is supposed to handle strings of unlimited length.
- What he probably wanted was read() to return a char* or to take a char**
- and then would either return B or assign the value of B to S i.e:
-
- return B;
- or
- *S = B;
-
- Missing return statement and in your example B needs to be free'd.
- free(B);
- return 1;
- : }
-
-
- My turn ;'):
- [* warning untested code. *]
-
- char*
- readString(void)
- {
- int ch;
- long count = 0;
- long size = 20; /* initial size */
- const int increment = 16;
- char* B = 0;
-
- B = malloc(size);
- if (!B)
- return 0;
-
- while ((ch = getchar()) != EOF && ch != '\n') {
- if (count == size - 1) {
- char* A = realloc(B, size += increment);
- if (!A) {
- free(B);
- return 0;
- } else {
- B = A;
- }
- }
- B[count++] = (char)ch;
- }
-
- /* There is a slight fudge in the condition for the realloc() that guarentees */
- /* one character spare for this assignment */
- B[count] = '\0';
-
- return B;
- }
-
- Hope this works ;')
- Regards
-
- -A.
- --
- | A.Champion |
-